/**
 * @file          Speaker.c
 * @brief         DY-SV5W Oneline 总线控制文件
 * @date          2024-07-19
 * @copyright Copyright (c) 2024
 */
#include "bsp_speaker.h"
#include "bsp_SysTick.h"

/**
 * @brief         语音播报模块初始化
 */
void GPIO_SPEAKER_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    /*使能GPIOD时钟*/
    RCC_AHB1PeriphClockCmd(SPEAKER_CLK, ENABLE);

    /*配置GPIO引脚*/
    GPIO_InitStruct.GPIO_Pin   = SPEAKER_PIN;
    GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd  = GPIO_PuPd_DOWN;
    GPIO_Init(SPEAKER_PORT, &GPIO_InitStruct);

    /*设置为高电平*/
    Oneline_H;

    // Speaker_MixCommand(10,VOLUME);
    //    Speaker_Broadcast(4);
}

/**
 * @brief         Speaker数据写入
 * @param         data
 * @date          2024-07-19
 */
void Speaker_SendData(unsigned char data)
{
    unsigned char shiftcnt = 0; // 高低电平转换次数
    Oneline_H;
    delay_ms(1);
    Oneline_L;
    delay_us(3200); // 删除会冲突
    for (shiftcnt = 0; shiftcnt < 8; shiftcnt++) {
        if (data & 0x01) // 高电平：1200us 高 + 400 低
        {
            Oneline_H;
            delay_us(1200); // 1200us
            Oneline_L;
            delay_us(400); // 400us
        } else             // 低电平：400us 高 + 1200 低
        {
            Oneline_H;
            delay_us(400); // 400us
            Oneline_L;
            delay_us(1200); // 1200us
        }
        data >>= 1;
    }
    Oneline_H; // 恢复线上高电平
}

/**
 * @brief         Speaker混合指令写入
 * @param         number 要调节的数值
 * @param         command 指令
 */

void Speaker_MixCommand(unsigned char number, unsigned char command)
{
    Speaker_SendData(number);
    Speaker_SendData(command);
}

/**
 * @brief         语音播报
 * @param         num 须播报的音频序号
 *                @arg 1 轻微干旱
 *                @arg 2 一般干旱
 *                @arg 3 严重干旱
 */
void Speaker_Broadcast(uint8_t num)
{
    int unit, ten, hundred; // 分别用于存储个位、十位、百位
    // Speaker_SendData(CLEAR);

    unit = num % 10;
    num /= 10;
    ten = num % 10;
    num /= 10;
    hundred = num;

    Speaker_SendData(hundred);
    Speaker_SendData(ten);
    Speaker_SendData(unit);
    Speaker_SendData(MUSIC_SELECT);
    delay_ms(3000); // 删除后会冲突
}
